package com.zjcloud.academic.service.impl;

import com.zjcloud.academic.domain.*;
import com.zjcloud.jwgl.domain.ScClass;
import com.zjcloud.jwgl.domain.ScTeacher;
import com.zjcloud.jwgl.domain.ScClassroom;
import com.zjcloud.jwgl.domain.ScCourse;
import com.zjcloud.academic.domain.AcSemester;
import com.zjcloud.academic.mapper.AcCourseScheduleMapper;
import com.zjcloud.academic.mapper.AcSemesterMapper;
import com.zjcloud.jwgl.service.IScCourseService;
import com.zjcloud.jwgl.service.IScClassService;
import com.zjcloud.jwgl.service.IScTeacherService;
import com.zjcloud.jwgl.service.IScClassroomService;
import com.zjcloud.academic.service.IntelligentScheduleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 智能排课算法服务实现类
 * 
 * @author zjcloud
 * @date 2024-12-19
 */
@Service
public class IntelligentScheduleServiceImpl implements IntelligentScheduleService {
    
    private static final Logger logger = LoggerFactory.getLogger(IntelligentScheduleServiceImpl.class);
    
    /**
     * 种群大小
     */
    private static final int POPULATION_SIZE = 30;
    
    /**
     * 精英比例
     */
    private static final double ELITE_PERCENTAGE = 0.2;

    /**
     * 获取排课统计信息
     * 
     * @param semesterId 学期ID
     * @return 统计信息
     */
    @Override
    public ScheduleStatistics getScheduleStatistics(Long semesterId) {
        ScheduleStatistics statistics = new ScheduleStatistics();
        
        try {
            // 获取该学期的所有排课
            List<AcCourseSchedule> schedules = courseScheduleMapper.selectAcCourseScheduleBySemesterId(semesterId);
            
            // 获取该学期的所有课程
            List<ScCourse> courses = courseService.selectScCourseBySemesterId(semesterId);
            
            // 基本统计
            statistics.setTotalCourses(courses.size());
            statistics.setScheduledCourses(schedules.size());
            
            // 冲突检测统计
            int conflictCount = 0;
            for (int i = 0; i < schedules.size(); i++) {
                for (int j = i + 1; j < schedules.size(); j++) {
                    AcCourseSchedule s1 = schedules.get(i);
                    AcCourseSchedule s2 = schedules.get(j);
                    
                    if (hasTimeConflict(s1, s2)) {
                        // 检查教师冲突
                        if (s1.getTeacherId().equals(s2.getTeacherId())) {
                            conflictCount++;
                        }
                        
                        // 检查教室冲突
                        if (s1.getClassroomId().equals(s2.getClassroomId())) {
                            conflictCount++;
                        }
                    }
                }
            }
            
            statistics.setConflictCount(conflictCount);
            
            // 计算资源利用率
            double utilizationRate = 0.0;
            if (!courses.isEmpty()) {
                utilizationRate = (double) schedules.size() / courses.size();
            }
            statistics.setUtilizationRate(utilizationRate);
            
        } catch (Exception e) {
            logger.error("获取排课统计信息失败: {}", e.getMessage(), e);
        }
        
        return statistics;
    }
    
    @Autowired
    @Qualifier("acCourseScheduleMapper")
    private AcCourseScheduleMapper courseScheduleMapper;
    
    @Autowired
    private IScCourseService courseService;
    
    @Autowired
    private IScClassService classService;
    
    @Autowired
    private IScTeacherService teacherService;
    
    @Autowired
    private IScClassroomService classroomService;
    
    @Autowired
    private AcSemesterMapper semesterMapper;

    /**
     * 使用遗传算法优化现有排课
     * 
     * @param existingSchedules 现有排课
     * @return 优化后的排课
     */
    private List<AcCourseSchedule> optimizeScheduleWithGeneticAlgorithm(List<AcCourseSchedule> existingSchedules) {
        if (existingSchedules == null || existingSchedules.isEmpty()) {
            return new ArrayList<>();
        }
        
        try {
            // 获取学期ID
            Long semesterId = existingSchedules.get(0).getSemesterId();
            
            // 获取学期信息
            AcSemester semester = semesterMapper.selectAcSemesterById(semesterId);
            if (semester == null) {
                logger.warn("学期不存在，ID: {}", semesterId);
                return existingSchedules;
            }
            
            // 获取相关的基础数据
            List<ScCourse> courses = courseService.selectScCourseBySemesterId(semesterId);
            List<ScClass> classes = classService.selectScClassList(new ScClass());
            List<ScTeacher> teachers = teacherService.selectScTeacherList(new ScTeacher());
            List<ScClassroom> classrooms = classroomService.selectScClassroomList(new ScClassroom());
            
            // 使用遗传算法优化现有排课
            Map<String, Object> algorithmConfig = new HashMap<>();
            algorithmConfig.put("populationSize", 30);
            algorithmConfig.put("maxGenerations", 50);
            algorithmConfig.put("mutationRate", 0.15);
            algorithmConfig.put("crossoverRate", 0.7);
            
            return optimizeWithGeneticAlgorithm(
                existingSchedules, courses, classes, teachers, classrooms, semester, algorithmConfig);
            
        } catch (Exception e) {
            logger.error("优化排课失败: {}", e.getMessage(), e);
            return existingSchedules;
        }
    }
    
    /**
     * 执行智能排课算法
     * 
     * @param semesterId 学期ID
     * @return 排课结果
     */
    @Override
    @Transactional
    public List<AcCourseSchedule> intelligentSchedule(Long semesterId) {
        return intelligentSchedule(semesterId, null);
    }

    /**
     * 优化现有排课
     * 
     * @param semesterId 学期ID
     * @return 优化后的排课结果
     */
    @Override
    @Transactional
    public List<AcCourseSchedule> optimizeSchedule(Long semesterId) {
        Logger logger = LoggerFactory.getLogger(IntelligentScheduleServiceImpl.class);
        try {
            logger.info("开始优化排课，学期ID: {}", semesterId);
            
            // 获取当前学期的所有排课
            List<AcCourseSchedule> existingSchedules = courseScheduleMapper.selectAcCourseScheduleBySemesterId(semesterId);
            if (existingSchedules.isEmpty()) {
                logger.warn("当前学期没有排课记录，无法进行优化");
                return new ArrayList<>();
            }
            
            // 使用遗传算法优化排课
            List<AcCourseSchedule> optimizedSchedules = optimizeScheduleWithGeneticAlgorithm(existingSchedules);
            
            logger.info("排课优化完成，共优化 {} 条记录", optimizedSchedules.size());
            return optimizedSchedules;
            
        } catch (Exception e) {
            logger.error("排课优化失败: ", e);
            throw new RuntimeException("排课优化失败: " + e.getMessage());
        }
    }
    
    /**
     * 优化现有排课（带操作用户）
     * 
     * @param semesterId 学期ID
     * @param operateUser 操作用户
     * @return 优化后的排课结果
     */
    @Override
    @Transactional
    public String optimizeSchedule(Long semesterId, String operateUser) {
        Logger logger = LoggerFactory.getLogger(IntelligentScheduleServiceImpl.class);
        
        try {
            logger.info("开始优化排课，学期ID: {}, 操作用户: {}", semesterId, operateUser);
            
            // 1. 获取学期信息
            AcSemester semester = semesterMapper.selectAcSemesterById(semesterId);
            if (semester == null) {
                throw new RuntimeException("学期不存在");
            }
            
            // 2. 获取该学期的现有排课
            List<AcCourseSchedule> existingSchedules = courseScheduleMapper.selectAcCourseScheduleBySemesterId(semesterId);
            if (existingSchedules.isEmpty()) {
                logger.warn("学期 {} 没有现有排课，无法进行优化", semesterId);
                return "该学期没有现有排课，无法进行优化";
            }
            
            logger.info("获取到 {} 条现有排课记录", existingSchedules.size());
            
            // 3. 获取相关的基础数据
            List<ScCourse> courses = courseService.selectScCourseBySemesterId(semesterId);
            List<ScClass> classes = classService.selectScClassList(new ScClass());
            List<ScTeacher> teachers = teacherService.selectScTeacherList(new ScTeacher());
            List<ScClassroom> classrooms = classroomService.selectScClassroomList(new ScClassroom());
            
            // 4. 使用遗传算法优化现有排课
            Map<String, Object> algorithmConfig = new HashMap<>();
            algorithmConfig.put("populationSize", 30);
            algorithmConfig.put("maxGenerations", 50);
            algorithmConfig.put("mutationRate", 0.15);
            algorithmConfig.put("crossoverRate", 0.7);
            
            List<AcCourseSchedule> optimizedSchedules = optimizeWithGeneticAlgorithm(
                existingSchedules, courses, classes, teachers, classrooms, semester, algorithmConfig);
            
            // 5. 保存优化结果
            if (optimizedSchedules != null && !optimizedSchedules.isEmpty()) {
                // 删除原有排课
                courseScheduleMapper.deleteAcCourseScheduleBySemesterId(semesterId);
                
                // 保存优化后的排课
                for (AcCourseSchedule schedule : optimizedSchedules) {
                    schedule.setCreateBy(operateUser);
                    schedule.setCreateTime(new Date());
                    courseScheduleMapper.insertAcCourseSchedule(schedule);
                }
                
                logger.info("排课优化完成，共优化 {} 条记录", optimizedSchedules.size());
                return "排课优化成功，共优化 " + optimizedSchedules.size() + " 条记录";
            } else {
                logger.warn("排课优化未能产生有效结果");
                return "排课优化未能产生有效结果";
            }
            
        } catch (Exception e) {
            logger.error("排课优化失败: {}", e.getMessage(), e);
            throw new RuntimeException("排课优化失败: " + e.getMessage(), e);
        }
    }

    /**
     * 执行智能排课算法（带进度回调）
     * 
     * @param semesterId 学期ID
     * @param progressCallback 进度回调接口
     * @return 排课结果
     */
    @Override
    @Transactional
    public List<AcCourseSchedule> intelligentSchedule(Long semesterId, IntelligentScheduleService.ProgressCallback progressCallback) {
        Logger logger = LoggerFactory.getLogger(IntelligentScheduleServiceImpl.class);
        
        try {
            // 1. 获取学期信息
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(5, "正在获取学期信息...");
            }
            AcSemester semester = semesterMapper.selectAcSemesterById(semesterId);
            if (semester == null) {
                throw new RuntimeException("学期不存在");
            }

            // 2. 获取该学期的所有课程
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(10, "正在获取课程信息...");
            }
            List<ScCourse> courses = courseService.selectScCourseBySemesterId(semesterId);
            if (courses.isEmpty()) {
                if (progressCallback != null) {
                    progressCallback.onComplete(new ArrayList<>());
                }
                return new ArrayList<>();
            }

            // 3. 获取班级、教师、教室信息
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(15, "正在获取班级、教师、教室信息...");
            }
            List<ScClass> classes = classService.selectScClassList(new ScClass());
            List<ScTeacher> teachers = teacherService.selectScTeacherList(new ScTeacher());
            List<ScClassroom> classrooms = classroomService.selectScClassroomList(new ScClassroom());

            // 4. 清空该学期原有课表
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(20, "正在清理历史课表...");
            }
            courseScheduleMapper.deleteAcCourseScheduleBySemesterId(semesterId);

            // 5. 执行遗传算法排课
            Map<String, Object> algorithmConfig = new HashMap<>();
            algorithmConfig.put("populationSize", 50);
            algorithmConfig.put("maxGenerations", 100);
            algorithmConfig.put("mutationRate", 0.1);
            algorithmConfig.put("crossoverRate", 0.8);
            
            boolean success = executeGeneticAlgorithm(courses, classes, teachers, classrooms, semester, algorithmConfig, progressCallback, "system");

            // 6. 返回排课结果
            List<AcCourseSchedule> result = courseScheduleMapper.selectAcCourseScheduleBySemesterId(semesterId);
            
            if (progressCallback != null) {
                if (success) {
                    progressCallback.onProgressUpdate(100, "排课完成！");
                    progressCallback.onComplete(result);
                } else {
                    progressCallback.onError("排课算法执行失败");
                }
            }
            
            return result;

        } catch (Exception e) {
            logger.error("排课失败: {}", e.getMessage(), e);
            if (progressCallback != null) {
                progressCallback.onError("排课失败: " + e.getMessage());
            }
            throw new RuntimeException("排课失败: " + e.getMessage(), e);
        }
    }

    /**
     * 遗传算法排课实现（带进度回调）
     */
    private boolean executeGeneticAlgorithm(List<ScCourse> courses, List<ScClass> classes, 
                                          List<ScTeacher> teachers, List<ScClassroom> classrooms,
                                          AcSemester semester, Map<String, Object> config,
                                          IntelligentScheduleService.ProgressCallback progressCallback,
                                          String operateUser) {
        
        int populationSize = Integer.parseInt(String.valueOf(config.getOrDefault("populationSize", 50)));
        int maxGenerations = Integer.parseInt(String.valueOf(config.getOrDefault("maxGenerations", 100)));
        double mutationRate = Double.parseDouble(String.valueOf(config.getOrDefault("mutationRate", 0.1)));
        double crossoverRate = Double.parseDouble(String.valueOf(config.getOrDefault("crossoverRate", 0.8)));

        Logger logger = LoggerFactory.getLogger(IntelligentScheduleServiceImpl.class);
        
        try {
            // 初始化种群
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(25, "正在初始化种群...");
            }
            List<ScheduleChromosome> population = initializePopulation(courses, classes, teachers, 
                                                                     classrooms, semester, populationSize);

            // 评估初始种群
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(30, "正在评估初始种群...");
            }
            evaluatePopulation(population);

            // 遗传算法主循环
            int progressStart = 30;
            int progressRange = 65;
            
            for (int generation = 0; generation < maxGenerations; generation++) {
                int progress = progressStart + (int)((double)generation / maxGenerations * progressRange);
                
                if (progressCallback != null) {
                    progressCallback.onProgressUpdate(progress, 
                        String.format("正在执行遗传算法第 %d/%d 代...", generation + 1, maxGenerations));
                }
                
                // 选择
                List<ScheduleChromosome> selected = selection(population);
                
                // 交叉
                List<ScheduleChromosome> offspring = crossover(selected, crossoverRate);
                
                // 变异
                mutate(offspring, mutationRate);
                
                // 评估新种群
                evaluatePopulation(offspring);
                
                // 精英保留
                population = elitism(population, offspring);
                
                // 检查是否达到最优解
                if (hasConverged(population)) {
                    logger.info("在第 {} 代收敛", generation + 1);
                    break;
                }
            }

            // 选择最优解并保存到数据库
            if (progressCallback != null) {
                progressCallback.onProgressUpdate(95, "正在保存排课结果...");
            }
            
            ScheduleChromosome bestSolution = getBestSolution(population);
            if (bestSolution == null) {
                logger.warn("未找到可行排课方案");
                return false;
            }
            
            saveScheduleToDatabase(bestSolution.getSchedules(), operateUser);
            return true;
            
        } catch (Exception e) {
            logger.error("遗传算法执行失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 初始化种群
     */
    private List<ScheduleChromosome> initializePopulation(List<ScCourse> courses, List<ScClass> classes,
                                                        List<ScTeacher> teachers, List<ScClassroom> classrooms,
                                                        AcSemester semester, int populationSize) {
        List<ScheduleChromosome> population = new ArrayList<>();
        
        for (int i = 0; i < populationSize; i++) {
            ScheduleChromosome chromosome = new ScheduleChromosome();
            List<AcCourseSchedule> schedules = new ArrayList<>();
            
            for (ScCourse course : courses) {
                // 为每个课程创建课表记录
                List<AcCourseSchedule> courseSchedules = generateCourseSchedules(course, classes, 
                                                                                teachers, classrooms, semester);
                schedules.addAll(courseSchedules);
            }
            
            chromosome.setSchedules(schedules);
            population.add(chromosome);
        }
        
        return population;
    }

    /**
     * 从现有课表初始化种群
     */
    private List<ScheduleChromosome> initializePopulationFromExisting(List<AcCourseSchedule> existingSchedules) {
        List<ScheduleChromosome> population = new ArrayList<>();
        
        // 基于现有课表创建初始种群
        for (int i = 0; i < 20; i++) {
            ScheduleChromosome chromosome = new ScheduleChromosome();
            List<AcCourseSchedule> schedules = new ArrayList<>();
            
            // 复制现有课表并进行变异
            for (AcCourseSchedule schedule : existingSchedules) {
                AcCourseSchedule newSchedule = deepCopySchedule(schedule);
                
                // 有一定概率进行变异
                if (Math.random() < 0.3) {
                    // 随机选择变异类型
                    int mutationType = (int) (Math.random() * 3);
                    
                    switch (mutationType) {
                        case 0: // 变更时间
                            int[] timeSlot = getRandomTimeSlot();
                            newSchedule.setWeekDay(timeSlot[0]);
                            Date[] times = convertPeriodToTime(timeSlot[1]);
                            newSchedule.setStartTime(times[0]);
                            newSchedule.setEndTime(times[1]);
                            break;
                            
                        case 1: // 变更教室
                            List<ScClassroom> classrooms = classroomService.selectScClassroomList(new ScClassroom());
                            if (!classrooms.isEmpty()) {
                                ScClassroom newClassroom = classrooms.get((int) (Math.random() * classrooms.size()));
                                newSchedule.setClassroomId(newClassroom.getId());
                            }
                            break;
                            
                        case 2: // 变更周次
                            int weekOffset = (int) (Math.random() * 3) - 1; // -1, 0, 1
                            int newStartWeek = Math.max(1, newSchedule.getStartWeek() + weekOffset);
                            int newEndWeek = Math.max(newStartWeek, newSchedule.getEndWeek() + weekOffset);
                            newSchedule.setStartWeek(newStartWeek);
                            newSchedule.setEndWeek(newEndWeek);
                            break;
                    }
                }
                
                schedules.add(newSchedule);
            }
            
            chromosome.setSchedules(schedules);
            population.add(chromosome);
        }
        
        return population;
    }

    /**
     * 生成单个课程的课表安排
     */
    private List<AcCourseSchedule> generateCourseSchedules(ScCourse course, List<ScClass> classes,
                                                         List<ScTeacher> teachers, List<ScClassroom> classrooms,
                                                         AcSemester semester) {
        List<AcCourseSchedule> schedules = new ArrayList<>();
        
        // 计算需要安排的总课时
        int totalHours = course.getTotalPeriods();
        int hoursPerWeek = course.getWeeklyPeriods();
        int weeks = totalHours / hoursPerWeek;
        
        // 获取相关班级、教师、教室
        List<ScClass> courseClasses = getCourseClasses(course, classes);
        List<ScTeacher> courseTeachers = getCourseTeachers(course, teachers);
        List<ScClassroom> suitableClassrooms = getSuitableClassrooms(course, classrooms);
        
        for (int week = 1; week <= weeks; week++) {
            // 随机选择时间槽
            int[] timeSlot = getRandomTimeSlot();
            int weekDay = timeSlot[0];
            int startPeriod = timeSlot[1];
            int endPeriod = startPeriod + hoursPerWeek - 1;
            
            // 随机选择教室和教师
            ScClassroom classroom = suitableClassrooms.get(new Random().nextInt(suitableClassrooms.size()));
            ScTeacher teacher = courseTeachers.get(new Random().nextInt(courseTeachers.size()));
            
            for (ScClass classItem : courseClasses) {
                AcCourseSchedule schedule = new AcCourseSchedule();
                schedule.setSemesterId(semester.getSemesterId());
                schedule.setCourseId(course.getId());
                schedule.setClassId(classItem.getId());
                schedule.setTeacherId(teacher.getId());
                schedule.setClassroomId(classroom.getId());
                schedule.setWeekDay(weekDay);
                // 转换时间段为时间
                Date[] times = convertPeriodToTime(startPeriod);
                schedule.setStartTime(times[0]);
                schedule.setEndTime(times[1]);
                schedule.setWeekType(1); // 全部周
                schedule.setStartWeek(week);
                schedule.setEndWeek(week);
                schedule.setStatus(1); // 正常状态
                
                schedules.add(schedule);
            }
        }
        
        return schedules;
    }

    /**
     * 评估种群适应度
     */
    private void evaluatePopulation(List<ScheduleChromosome> population) {
        for (ScheduleChromosome chromosome : population) {
            double fitness = calculateFitness(chromosome);
            chromosome.setFitness(fitness);
        }
    }

    /**
     * 计算适应度
     */
    private double calculateFitness(ScheduleChromosome chromosome) {
        double fitness = 100.0;
        List<AcCourseSchedule> schedules = chromosome.getSchedules();
        
        // 检查硬约束冲突
        fitness -= checkHardConstraints(schedules) * 10;
        
        // 检查软约束冲突
        fitness -= checkSoftConstraints(schedules) * 5;
        
        // 优化目标：教室利用率、时间分布均匀性等
        fitness += calculateOptimizationScore(schedules);
        
        return Math.max(fitness, 0);
    }

    /**
     * 检查硬约束（改进版）
     */
    private double checkHardConstraints(List<AcCourseSchedule> schedules) {
        double score = 1.0;
        int totalChecks = 0;
        int passedChecks = 0;
        
        for (int i = 0; i < schedules.size(); i++) {
            for (int j = i + 1; j < schedules.size(); j++) {
                AcCourseSchedule s1 = schedules.get(i);
                AcCourseSchedule s2 = schedules.get(j);
                
                // 检查时间冲突
                if (hasTimeConflict(s1, s2)) {
                    // 检查教师冲突
                    totalChecks++;
                    if (!s1.getTeacherId().equals(s2.getTeacherId())) {
                        passedChecks++;
                    }
                    
                    // 检查教室冲突
                    totalChecks++;
                    if (!s1.getClassroomId().equals(s2.getClassroomId())) {
                        passedChecks++;
                    }
                    
                    // 检查班级冲突
                    totalChecks++;
                    if (!s1.getClassId().equals(s2.getClassId())) {
                        passedChecks++;
                    }
                }
            }
        }
        
        // 检查教室容量
        totalChecks += schedules.size();
        passedChecks += checkClassroomCapacity(schedules);
        
        return totalChecks > 0 ? (double) passedChecks / totalChecks : 1.0;
    }

    

    /**
     * 检查软约束（改进版）
     */
    private double checkSoftConstraints(List<AcCourseSchedule> schedules) {
        double score = 0.0;
        int totalChecks = 0;
        int passedChecks = 0;
        
        // 检查课程是否安排在下午（软约束）
        for (AcCourseSchedule schedule : schedules) {
            totalChecks++;
            if (isAfternoon(schedule.getStartTime())) {
                passedChecks++;
            }
        }
        
        // 检查教师课程分布均衡性
        totalChecks++;
        if (checkTeacherWorkloadBalance(schedules)) {
            passedChecks++;
        }
        
        // 检查班级课程分布均衡性
        totalChecks++;
        if (checkClassScheduleBalance(schedules)) {
            passedChecks++;
        }
        
        return totalChecks > 0 ? (double) passedChecks / totalChecks : 0.0;
    }
    
    /**
     * 检查教室容量约束
     */
    private int checkClassroomCapacity(List<AcCourseSchedule> schedules) {
        int passedChecks = 0;
        
        for (AcCourseSchedule schedule : schedules) {
            // 获取课程信息
            ScCourse course = courseService.selectScCourseById(schedule.getCourseId());
            if (course == null) {
                continue;
            }
            
            // 获取教室信息
            ScClassroom classroom = classroomService.selectScClassroomById(schedule.getClassroomId());
            if (classroom == null) {
                continue;
            }
            
            // 获取班级信息
            ScClass classInfo = classService.selectScClassById(schedule.getClassId());
            if (classInfo == null) {
                continue;
            }
            
            // 检查教室容量是否足够
            if (classroom.getCapacity() >= classInfo.getStudentCount()) {
                passedChecks++;
            }
        }
        
        return passedChecks;
    }
    
    /**
     * 检查教师工作量均衡性
     */
    private boolean checkTeacherWorkloadBalance(List<AcCourseSchedule> schedules) {
        // 统计每个教师的课程数量
        Map<Long, Integer> teacherCourseCount = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Long teacherId = schedule.getTeacherId();
            teacherCourseCount.put(teacherId, teacherCourseCount.getOrDefault(teacherId, 0) + 1);
        }
        
        // 计算标准差，评估均衡性
        if (teacherCourseCount.isEmpty()) {
            return true;
        }
        
        double average = teacherCourseCount.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        
        double variance = teacherCourseCount.values().stream()
                .mapToDouble(count -> Math.pow(count - average, 2))
                .average()
                .orElse(0);
        
        double stdDev = Math.sqrt(variance);
        
        // 标准差小于平均值的30%认为是均衡的
        return stdDev < average * 0.3;
    }
    
    /**
     * 检查班级课程分布均衡性
     */
    private boolean checkClassScheduleBalance(List<AcCourseSchedule> schedules) {
        // 统计每个班级的课程数量
        Map<Long, Integer> classCourseCount = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Long classId = schedule.getClassId();
            classCourseCount.put(classId, classCourseCount.getOrDefault(classId, 0) + 1);
        }
        
        // 计算标准差，评估均衡性
        if (classCourseCount.isEmpty()) {
            return true;
        }
        
        double average = classCourseCount.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        
        double variance = classCourseCount.values().stream()
                .mapToDouble(count -> Math.pow(count - average, 2))
                .average()
                .orElse(0);
        
        double stdDev = Math.sqrt(variance);
        
        // 标准差小于平均值的30%认为是均衡的
        return stdDev < average * 0.3;
    }

    /**
     * 计算优化目标得分（改进版）
     */
    private double calculateOptimizationScore(List<AcCourseSchedule> schedules) {
        double score = 0.0;
        int totalGoals = 0;
        
        // 1. 教室利用率
        double classroomUtilization = calculateClassroomUtilization(schedules);
        score += classroomUtilization;
        totalGoals++;
        
        // 2. 教师工作量均衡性
        double teacherBalance = calculateTeacherWorkloadBalance(schedules);
        score += teacherBalance;
        totalGoals++;
        
        // 3. 班级课程分布均衡性
        double classBalance = calculateClassScheduleBalance(schedules);
        score += classBalance;
        totalGoals++;
        
        // 4. 课程时间分布合理性
        double timeDistribution = calculateTimeDistributionReasonableness(schedules);
        score += timeDistribution;
        totalGoals++;
        
        // 5. 特殊课程优先安排在上午
        double specialCourseArrangement = calculateSpecialCourseArrangement(schedules);
        score += specialCourseArrangement;
        totalGoals++;
        
        return totalGoals > 0 ? score / totalGoals : 0.0;
    }
    
    /**
     * 计算教室利用率
     */
    private double calculateClassroomUtilization(List<AcCourseSchedule> schedules) {
        if (schedules.isEmpty()) {
            return 0.0;
        }
        
        // 统计每个教室的使用时间
        Map<Long, Long> classroomUsageMinutes = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Long classroomId = schedule.getClassroomId();
            long duration = (schedule.getEndTime().getTime() - schedule.getStartTime().getTime()) / (60 * 1000); // 分钟
            classroomUsageMinutes.put(classroomId, classroomUsageMinutes.getOrDefault(classroomId, 0L) + duration);
        }
        
        // 计算总可用时间（假设每周5天，每天8小时）
        long totalAvailableMinutes = classroomUsageMinutes.size() * 5 * 8 * 60;
        
        // 计算实际使用时间
        long totalUsedMinutes = classroomUsageMinutes.values().stream().mapToLong(Long::longValue).sum();
        
        return totalAvailableMinutes > 0 ? (double) totalUsedMinutes / totalAvailableMinutes : 0.0;
    }
    
    /**
     * 计算教师工作量均衡性得分
     */
    private double calculateTeacherWorkloadBalance(List<AcCourseSchedule> schedules) {
        // 统计每个教师的课程数量
        Map<Long, Integer> teacherCourseCount = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Long teacherId = schedule.getTeacherId();
            teacherCourseCount.put(teacherId, teacherCourseCount.getOrDefault(teacherId, 0) + 1);
        }
        
        if (teacherCourseCount.isEmpty()) {
            return 1.0;
        }
        
        // 计算标准差，评估均衡性
        double average = teacherCourseCount.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        
        if (average == 0) {
            return 1.0;
        }
        
        double variance = teacherCourseCount.values().stream()
                .mapToDouble(count -> Math.pow(count - average, 2))
                .average()
                .orElse(0);
        
        double stdDev = Math.sqrt(variance);
        
        // 标准差越小，均衡性越好，得分越高
        // 使用指数函数将标准差转换为0-1之间的得分
        return Math.exp(-stdDev / average);
    }
    
    /**
     * 计算班级课程分布均衡性得分
     */
    private double calculateClassScheduleBalance(List<AcCourseSchedule> schedules) {
        // 统计每个班级的课程数量
        Map<Long, Integer> classCourseCount = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Long classId = schedule.getClassId();
            classCourseCount.put(classId, classCourseCount.getOrDefault(classId, 0) + 1);
        }
        
        if (classCourseCount.isEmpty()) {
            return 1.0;
        }
        
        // 计算标准差，评估均衡性
        double average = classCourseCount.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        
        if (average == 0) {
            return 1.0;
        }
        
        double variance = classCourseCount.values().stream()
                .mapToDouble(count -> Math.pow(count - average, 2))
                .average()
                .orElse(0);
        
        double stdDev = Math.sqrt(variance);
        
        // 标准差越小，均衡性越好，得分越高
        return Math.exp(-stdDev / average);
    }
    
    /**
     * 计算课程时间分布合理性得分
     */
    private double calculateTimeDistributionReasonableness(List<AcCourseSchedule> schedules) {
        if (schedules.isEmpty()) {
            return 0.0;
        }
        
        // 统计每个时间段（星期几+第几节课）的课程数量
        Map<String, Integer> timeSlotCount = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(schedule.getStartTime());
            int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1; // 0-6表示周一到周日
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            
            // 将小时转换为节次（假设每节课45分钟，休息10分钟）
            int period = (hour - 8) * 60 / 55; // 假设8点开始上课
            
            String timeSlot = dayOfWeek + "-" + period;
            timeSlotCount.put(timeSlot, timeSlotCount.getOrDefault(timeSlot, 0) + 1);
        }
        
        // 计算标准差，评估均衡性
        if (timeSlotCount.isEmpty()) {
            return 1.0;
        }
        
        double average = timeSlotCount.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0);
        
        if (average == 0) {
            return 1.0;
        }
        
        double variance = timeSlotCount.values().stream()
                .mapToDouble(count -> Math.pow(count - average, 2))
                .average()
                .orElse(0);
        
        double stdDev = Math.sqrt(variance);
        
        // 标准差越小，分布越均衡，得分越高
        return Math.exp(-stdDev / average);
    }
    
    /**
     * 计算特殊课程优先安排在上午的得分
     */
    private double calculateSpecialCourseArrangement(List<AcCourseSchedule> schedules) {
        if (schedules.isEmpty()) {
            return 0.0;
        }
        
        int specialCourses = 0;
        int morningArranged = 0;
        
        for (AcCourseSchedule schedule : schedules) {
            // 获取课程信息
            ScCourse course = courseService.selectScCourseById(schedule.getCourseId());
            if (course == null) {
                continue;
            }
            
            // 假设重要课程（如必修课、核心课）需要优先安排在上午
            if (course.getCourseType() != null && 
                (course.getCourseType().equals("必修") || course.getCourseType().equals("核心"))) {
                specialCourses++;
                
                // 检查是否安排在上午
                Calendar cal = Calendar.getInstance();
                cal.setTime(schedule.getStartTime());
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                
                if (hour < 12) { // 12点前算上午
                    morningArranged++;
                }
            }
        }
        
        return specialCourses > 0 ? (double) morningArranged / specialCourses : 1.0;
    }

    /**
     * 选择操作
     */
    private List<ScheduleChromosome> selection(List<ScheduleChromosome> population) {
        // 轮盘赌选择
        double totalFitness = population.stream().mapToDouble(ScheduleChromosome::getFitness).sum();
        List<ScheduleChromosome> selected = new ArrayList<>();
        
        for (int i = 0; i < population.size(); i++) {
            double random = Math.random() * totalFitness;
            double sum = 0;
            
            for (ScheduleChromosome chromosome : population) {
                sum += chromosome.getFitness();
                if (sum >= random) {
                    selected.add(chromosome);
                    break;
                }
            }
        }
        
        return selected;
    }

    /**
     * 精英保留
     */
    private List<ScheduleChromosome> elitismSelection(List<ScheduleChromosome> oldPopulation, 
                                                      List<ScheduleChromosome> newPopulation) {
        // 保留精英个体
        int eliteCount = (int) (POPULATION_SIZE * ELITE_PERCENTAGE);
        
        oldPopulation.sort((a, b) -> Double.compare(b.getFitness(), a.getFitness()));
        newPopulation.sort((a, b) -> Double.compare(b.getFitness(), a.getFitness()));
        
        List<ScheduleChromosome> result = new ArrayList<>();
        
        // 添加精英个体
        for (int i = 0; i < eliteCount && i < oldPopulation.size(); i++) {
            result.add(oldPopulation.get(i));
        }
        
        // 添加新个体
        for (int i = 0; i < newPopulation.size() && result.size() < POPULATION_SIZE; i++) {
            if (!isDuplicate(result, newPopulation.get(i))) {
                result.add(newPopulation.get(i));
            }
        }
        
        return result;
    }

    /**
     * 检查重复个体
     */
    private boolean isDuplicate(List<ScheduleChromosome> population, ScheduleChromosome chromosome) {
        return population.stream()
                .anyMatch(individual -> calculateSimilarity(individual, chromosome) > 0.95);
    }

    /**
     * 计算个体相似度
     */
    private double calculateSimilarity(ScheduleChromosome a, ScheduleChromosome b) {
        List<AcCourseSchedule> genesA = a.getSchedules();
        List<AcCourseSchedule> genesB = b.getSchedules();
        
        if (genesA.size() != genesB.size()) {
            return 0.0;
        }
        
        int sameCount = 0;
        for (int i = 0; i < genesA.size(); i++) {
            if (genesA.get(i).equals(genesB.get(i))) {
                sameCount++;
            }
        }
        
        return (double) sameCount / genesA.size();
    }

    /**
     * 归一化适应度
     */
    private void normalizeFitness(List<ScheduleChromosome> population) {
        double minFitness = population.stream().mapToDouble(ScheduleChromosome::getFitness).min().orElse(0);
        double maxFitness = population.stream().mapToDouble(ScheduleChromosome::getFitness).max().orElse(1);
        
        if (maxFitness - minFitness > 0.001) {
            for (ScheduleChromosome chromosome : population) {
                double normalized = (chromosome.getFitness() - minFitness) / (maxFitness - minFitness);
                chromosome.setFitness(normalized);
            }
        }
    }

    /**
     * 获取最佳适应度
     */
    private double getBestFitness(List<ScheduleChromosome> population) {
        return population.stream().mapToDouble(ScheduleChromosome::getFitness).max().orElse(0);
    }

    /**
     * 检查时间冲突
     */
    private boolean hasTimeConflict(AcCourseSchedule s1, AcCourseSchedule s2) {
        return s1.getWeekDay().equals(s2.getWeekDay()) &&
               s1.getStartWeek() <= s2.getEndWeek() &&
               s2.getStartWeek() <= s1.getEndWeek() &&
               s1.getStartTime().getTime() <= s2.getEndTime().getTime() &&
               s2.getStartTime().getTime() <= s1.getEndTime().getTime();
    }

    

    /**
     * 检查教师偏好
     */
    private double checkTeacherPreferences(List<AcCourseSchedule> schedules) {
        // 简化实现：检查课程是否安排在上午（假设教师偏好上午）
        int totalChecks = schedules.size();
        int passedChecks = 0;
        
        for (AcCourseSchedule schedule : schedules) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(schedule.getStartTime());
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            if (hour <= 12) { // 上午
                passedChecks++;
            }
        }
        
        return totalChecks > 0 ? (double) passedChecks / totalChecks : 1.0;
    }

    /**
     * 检查课程分布均匀性
     */
    private double checkCourseDistribution(List<AcCourseSchedule> schedules) {
        // 简化实现：检查课程是否均匀分布在各天
        Map<Integer, Integer> dayCount = new HashMap<>();
        
        for (AcCourseSchedule schedule : schedules) {
            dayCount.put(schedule.getWeekDay(), dayCount.getOrDefault(schedule.getWeekDay(), 0) + 1);
        }
        
        // 计算标准差，标准差越小分布越均匀
        double average = (double) schedules.size() / 5; // 5个工作日
        double variance = 0;
        
        for (int day = 1; day <= 5; day++) {
            int count = dayCount.getOrDefault(day, 0);
            variance += Math.pow(count - average, 2);
        }
        
        variance /= 5;
        double stdDev = Math.sqrt(variance);
        
        // 标准差转换为分数，标准差越小分数越高
        return Math.max(0, 1 - stdDev / average);
    }

    /**
     * 检查教室类型匹配
     */
    private double checkClassroomTypeMatch(List<AcCourseSchedule> schedules) {
        // 简化实现：假设所有教室都合适
        return 1.0;
    }

    /**
     * 检查学生课业负担均衡
     */
    private double checkStudentWorkloadBalance(List<AcCourseSchedule> schedules) {
        // 简化实现：检查每个班级的课时分布
        Map<Long, Integer> classHours = new HashMap<>();
        
        for (AcCourseSchedule schedule : schedules) {
            classHours.put(schedule.getClassId(), classHours.getOrDefault(schedule.getClassId(), 0) + 1);
        }
        
        // 计算标准差，标准差越小分布越均衡
        double average = classHours.values().stream().mapToInt(Integer::intValue).average().orElse(0);
        double variance = 0;
        
        for (int hours : classHours.values()) {
            variance += Math.pow(hours - average, 2);
        }
        
        variance /= classHours.size();
        double stdDev = Math.sqrt(variance);
        
        // 标准差转换为分数，标准差越小分数越高
        return average > 0 ? Math.max(0, 1 - stdDev / average) : 1.0;
    }

    

    /**
     * 计算课程连续性
     */
    private double calculateCourseContinuity(List<AcCourseSchedule> schedules) {
        // 简化实现：检查同一课程是否连续安排
        Map<Long, List<AcCourseSchedule>> courseSchedules = new HashMap<>();
        
        for (AcCourseSchedule schedule : schedules) {
            courseSchedules.computeIfAbsent(schedule.getCourseId(), k -> new ArrayList<>()).add(schedule);
        }
        
        double totalScore = 0;
        int courseCount = 0;
        
        for (List<AcCourseSchedule> courseScheduleList : courseSchedules.values()) {
            // 按时间排序
            courseScheduleList.sort(Comparator.comparing(AcCourseSchedule::getStartTime));
            
            // 检查连续性
            int consecutiveCount = 0;
            for (int i = 1; i < courseScheduleList.size(); i++) {
                AcCourseSchedule prev = courseScheduleList.get(i - 1);
                AcCourseSchedule curr = courseScheduleList.get(i);
                
                // 检查是否是连续的周次
                if (curr.getStartWeek() == prev.getEndWeek() + 1) {
                    consecutiveCount++;
                }
            }
            
            // 计算连续性得分
            double continuityScore = courseScheduleList.size() > 1 ? 
                (double) consecutiveCount / (courseScheduleList.size() - 1) : 1.0;
            
            totalScore += continuityScore;
            courseCount++;
        }
        
        return courseCount > 0 ? totalScore / courseCount : 1.0;
    }

    /**
     * 计算时间偏好满足度
     */
    private double calculateTimePreferenceSatisfaction(List<AcCourseSchedule> schedules) {
        // 简化实现：检查重要课程是否安排在上午
        // 假设总课时大于等于4的课程为重要课程
        int importantCourses = 0;
        int morningArranged = 0;
        
        Map<Long, Integer> courseHours = new HashMap<>();
        for (AcCourseSchedule schedule : schedules) {
            courseHours.put(schedule.getCourseId(), courseHours.getOrDefault(schedule.getCourseId(), 0) + 1);
        }
        
        for (AcCourseSchedule schedule : schedules) {
            if (courseHours.get(schedule.getCourseId()) >= 4) {
                importantCourses++;
                
                Calendar cal = Calendar.getInstance();
                cal.setTime(schedule.getStartTime());
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                
                if (hour <= 12) { // 上午
                    morningArranged++;
                }
            }
        }
        
        return importantCourses > 0 ? (double) morningArranged / importantCourses : 1.0;
    }

    /**
     * 锦标赛选择
     * @param population 种群
     * @return 选择的个体
     */
    private List<ScheduleChromosome> tournamentSelection(List<ScheduleChromosome> population) {
        List<ScheduleChromosome> selected = new ArrayList<>();
        int tournamentSize = 3; // 锦标赛大小
        
        for (int i = 0; i < population.size(); i++) {
            // 随机选择tournamentSize个个体
            List<ScheduleChromosome> tournament = new ArrayList<>();
            Random random = new Random();
            
            for (int j = 0; j < tournamentSize; j++) {
                int index = random.nextInt(population.size());
                tournament.add(population.get(index));
            }
            
            // 选择适应度最高的个体
            ScheduleChromosome winner = tournament.stream()
                .max(Comparator.comparingDouble(ScheduleChromosome::getFitness))
                .orElse(null);
            
            if (winner != null) {
                selected.add(winner);
            }
        }
        
        return selected;
    }

    /**
     * 交叉操作
     * @param parents 父代种群
     * @param crossoverRate 交叉率
     * @return 子代种群
     */
    private List<ScheduleChromosome> crossover(List<ScheduleChromosome> parents, double crossoverRate) {
        List<ScheduleChromosome> offspring = new ArrayList<>();
        Random random = new Random();
        
        // 确保父代数量是偶数
        if (parents.size() % 2 != 0) {
            offspring.add(parents.get(0));
            parents = parents.subList(1, parents.size());
        }
        
        for (int i = 0; i < parents.size(); i += 2) {
            ScheduleChromosome parent1 = parents.get(i);
            ScheduleChromosome parent2 = parents.get(i + 1);
            
            if (random.nextDouble() < crossoverRate) {
                // 执行交叉
                ScheduleChromosome[] children = performCrossover(parent1, parent2);
                offspring.add(children[0]);
                offspring.add(children[1]);
            } else {
                // 不交叉，直接复制
                offspring.add(deepCopyChromosome(parent1));
                offspring.add(deepCopyChromosome(parent2));
            }
        }
        
        return offspring;
    }

    /**
     * 执行交叉操作
     * @param parent1 父代1
     * @param parent2 父代2
     * @return 子代数组
     */
    private ScheduleChromosome[] performCrossover(ScheduleChromosome parent1, ScheduleChromosome parent2) {
        ScheduleChromosome child1 = new ScheduleChromosome();
        ScheduleChromosome child2 = new ScheduleChromosome();
        
        List<AcCourseSchedule> schedules1 = new ArrayList<>();
        List<AcCourseSchedule> schedules2 = new ArrayList<>();
        
        List<AcCourseSchedule> parentSchedules1 = parent1.getSchedules();
        List<AcCourseSchedule> parentSchedules2 = parent2.getSchedules();
        
        Random random = new Random();
        int crossoverPoint = random.nextInt(parentSchedules1.size());
        
        // 单点交叉
        for (int i = 0; i < parentSchedules1.size(); i++) {
            if (i < crossoverPoint) {
                schedules1.add(deepCopySchedule(parentSchedules1.get(i)));
                schedules2.add(deepCopySchedule(parentSchedules2.get(i)));
            } else {
                schedules1.add(deepCopySchedule(parentSchedules2.get(i)));
                schedules2.add(deepCopySchedule(parentSchedules1.get(i)));
            }
        }
        
        child1.setSchedules(schedules1);
        child2.setSchedules(schedules2);
        
        return new ScheduleChromosome[]{child1, child2};
    }

    /**
     * 变异操作
     * @param population 种群
     * @param mutationRate 变异率
     */
    private void mutate(List<ScheduleChromosome> population, double mutationRate) {
        Random random = new Random();
        
        for (ScheduleChromosome chromosome : population) {
            if (random.nextDouble() < mutationRate) {
                // 执行变异
                performMutation(chromosome);
            }
        }
    }

    /**
     * 执行变异操作
     * @param chromosome 染色体
     */
    private void performMutation(ScheduleChromosome chromosome) {
        List<AcCourseSchedule> schedules = chromosome.getSchedules();
        Random random = new Random();
        
        // 随机选择一个课程安排进行变异
        int mutateIndex = random.nextInt(schedules.size());
        AcCourseSchedule schedule = schedules.get(mutateIndex);
        
        // 随机选择变异类型
        int mutationType = random.nextInt(3);
        
        switch (mutationType) {
            case 0: // 变更时间
                int[] timeSlot = getRandomTimeSlot();
                schedule.setWeekDay(timeSlot[0]);
                Date[] times = convertPeriodToTime(timeSlot[1]);
                schedule.setStartTime(times[0]);
                schedule.setEndTime(times[1]);
                break;
                
            case 1: // 变更教室
                List<ScClassroom> classrooms = classroomService.selectScClassroomList(new ScClassroom());
                if (!classrooms.isEmpty()) {
                    ScClassroom newClassroom = classrooms.get(random.nextInt(classrooms.size()));
                    schedule.setClassroomId(newClassroom.getId());
                }
                break;
                
            case 2: // 交换两个课程的时间
                if (schedules.size() > 1) {
                    int swapIndex = random.nextInt(schedules.size());
                    if (swapIndex != mutateIndex) {
                        AcCourseSchedule otherSchedule = schedules.get(swapIndex);
                        
                        // 交换星期几
                        int tempWeekDay = schedule.getWeekDay();
                        schedule.setWeekDay(otherSchedule.getWeekDay());
                        otherSchedule.setWeekDay(tempWeekDay);
                        
                        // 交换开始时间
                        Date tempStartTime = schedule.getStartTime();
                        schedule.setStartTime(otherSchedule.getStartTime());
                        otherSchedule.setStartTime(tempStartTime);
                        
                        // 交换结束时间
                        Date tempEndTime = schedule.getEndTime();
                        schedule.setEndTime(otherSchedule.getEndTime());
                        otherSchedule.setEndTime(tempEndTime);
                    }
                }
                break;
        }
    }

    

    /**
     * 获取最优解
     * @param population 种群
     * @return 最优解
     */
    private ScheduleChromosome getBestSolution(List<ScheduleChromosome> population) {
        return population.stream()
            .max(Comparator.comparingDouble(ScheduleChromosome::getFitness))
            .orElse(null);
    }

    /**
     * 深度复制染色体
     * @param chromosome 源染色体
     * @return 复制的染色体
     */
    private ScheduleChromosome deepCopyChromosome(ScheduleChromosome chromosome) {
        ScheduleChromosome copy = new ScheduleChromosome();
        List<AcCourseSchedule> schedules = new ArrayList<>();
        
        for (AcCourseSchedule schedule : chromosome.getSchedules()) {
            schedules.add(deepCopySchedule(schedule));
        }
        
        copy.setSchedules(schedules);
        copy.setFitness(chromosome.getFitness());
        
        return copy;
    }

    /**
     * 深度复制课程安排
     * @param schedule 源课程安排
     * @return 复制的课程安排
     */
    private AcCourseSchedule deepCopySchedule(AcCourseSchedule schedule) {
        AcCourseSchedule copy = new AcCourseSchedule();
        copy.setSemesterId(schedule.getSemesterId());
        copy.setCourseId(schedule.getCourseId());
        copy.setClassId(schedule.getClassId());
        copy.setTeacherId(schedule.getTeacherId());
        copy.setClassroomId(schedule.getClassroomId());
        copy.setWeekDay(schedule.getWeekDay());
        copy.setStartTime(schedule.getStartTime());
        copy.setEndTime(schedule.getEndTime());
        copy.setWeekType(schedule.getWeekType());
        copy.setStartWeek(schedule.getStartWeek());
        copy.setEndWeek(schedule.getEndWeek());
        copy.setStatus(schedule.getStatus());
        
        return copy;
    }

    

    private List<AcCourseSchedule> optimizeWithGeneticAlgorithm(List<AcCourseSchedule> existingSchedules, List<ScCourse> courses, List<ScClass> classes, List<ScTeacher> teachers, List<ScClassroom> classrooms, AcSemester semester, Map<String, Object> algorithmConfig) {
        // 使用改进的遗传算法优化排课
        List<ScheduleChromosome> population = initializePopulationFromExisting(existingSchedules);
        
        // 评估初始种群
        evaluatePopulation(population);
        
        int generation = 0;
        int maxGenerations = Integer.parseInt(String.valueOf(algorithmConfig.getOrDefault("maxGenerations", 50)));
        double mutationRate = Double.parseDouble(String.valueOf(algorithmConfig.getOrDefault("mutationRate", 0.15)));
        double crossoverRate = Double.parseDouble(String.valueOf(algorithmConfig.getOrDefault("crossoverRate", 0.7)));
        double bestFitness = 0.0;
        int stagnationCount = 0;
        
        while (generation < maxGenerations && stagnationCount < 20) {
            // 选择
            List<ScheduleChromosome> selected = selection(population);
            
            // 交叉
            List<ScheduleChromosome> offspring = crossover(selected, crossoverRate);
            
            // 变异
            mutate(offspring, mutationRate);
            
            // 评估后代
            evaluatePopulation(offspring);
            
            // 精英保留
            population = elitismSelection(population, offspring);
            
            // 检查收敛性
            double currentBestFitness = getBestFitness(population);
            if (currentBestFitness - bestFitness < 0.001) {
                stagnationCount++;
            } else {
                stagnationCount = 0;
                bestFitness = currentBestFitness;
            }
            
            generation++;
        }
        
        // 返回最优解
        ScheduleChromosome bestSolution = getBestSolution(population);
        return bestSolution != null ? bestSolution.getSchedules() : existingSchedules;
    }

    /**
     * 获取随机时间槽
     * @return 时间槽数组，[0]为星期几，[1]为节次
     */
    private int[] getRandomTimeSlot() {
        Random random = new Random();
        int weekDay = random.nextInt(5) + 1; // 1-5，周一到周五
        int period = random.nextInt(8) + 1; // 1-8，第1-8节
        return new int[]{weekDay, period};
    }

    /**
     * 将节次转换为时间
     * @param period 节次
     * @return 时间数组，[0]为开始时间，[1]为结束时间
     */
    private Date[] convertPeriodToTime(int period) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 8); // 8点开始
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        
        // 每节课45分钟，休息10分钟
        int minutesPerClass = 45;
        int minutesBreak = 10;
        
        // 计算开始时间
        int totalMinutes = (period - 1) * (minutesPerClass + minutesBreak);
        calendar.add(Calendar.MINUTE, totalMinutes);
        Date startTime = calendar.getTime();
        
        // 计算结束时间
        calendar.add(Calendar.MINUTE, minutesPerClass);
        Date endTime = calendar.getTime();
        
        return new Date[]{startTime, endTime};
    }
    
    /**
     * 获取课程的班级列表
     */
    private List<ScClass> getCourseClasses(ScCourse course, List<ScClass> allClasses) {
        List<ScClass> result = new ArrayList<>();
        // 简化实现：随机选择一些班级
        // 实际应用中应根据课程与班级的关联关系获取
        int classCount = Math.min(3, allClasses.size()); // 最多选择3个班级
        Random random = new Random();
        
        for (int i = 0; i < classCount; i++) {
            int index = random.nextInt(allClasses.size());
            result.add(allClasses.get(index));
        }
        
        return result;
    }
    
    /**
     * 获取课程的教师列表
     */
    private List<ScTeacher> getCourseTeachers(ScCourse course, List<ScTeacher> allTeachers) {
        List<ScTeacher> result = new ArrayList<>();
        // 简化实现：随机选择一些教师
        // 实际应用中应根据课程与教师的关联关系获取
        int teacherCount = Math.min(2, allTeachers.size()); // 最多选择2个教师
        Random random = new Random();
        
        for (int i = 0; i < teacherCount; i++) {
            int index = random.nextInt(allTeachers.size());
            result.add(allTeachers.get(index));
        }
        
        return result;
    }
    
    /**
     * 获取适合课程的教室列表
     */
    private List<ScClassroom> getSuitableClassrooms(ScCourse course, List<ScClassroom> allClassrooms) {
        List<ScClassroom> result = new ArrayList<>();
        // 简化实现：随机选择一些教室
        // 实际应用中应根据课程类型和教室类型匹配获取
        int classroomCount = Math.min(5, allClassrooms.size()); // 最多选择5个教室
        Random random = new Random();
        
        for (int i = 0; i < classroomCount; i++) {
            int index = random.nextInt(allClassrooms.size());
            result.add(allClassrooms.get(index));
        }
        
        return result;
    }
    
    /**
     * 判断时间是否在下午
     */
    private boolean isAfternoon(Date time) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        return hour >= 12; // 12点及以后算下午
    }
    
    /**
     * 精英选择
     */
    private List<ScheduleChromosome> elitism(List<ScheduleChromosome> population, List<ScheduleChromosome> offspring) {
        // 合并父代和子代
        List<ScheduleChromosome> combined = new ArrayList<>();
        combined.addAll(population);
        combined.addAll(offspring);
        
        // 按适应度排序
        combined.sort((c1, c2) -> Double.compare(c2.getFitness(), c1.getFitness()));
        
        // 选择前ELITE_PERCENTAGE比例的个体
        int eliteCount = (int) (POPULATION_SIZE * ELITE_PERCENTAGE);
        List<ScheduleChromosome> newPopulation = new ArrayList<>();
        
        for (int i = 0; i < eliteCount && i < combined.size(); i++) {
            newPopulation.add(combined.get(i));
        }
        
        // 填充剩余位置
        while (newPopulation.size() < POPULATION_SIZE && newPopulation.size() < combined.size()) {
            newPopulation.add(combined.get(newPopulation.size()));
        }
        
        return newPopulation;
    }
    
    
    
    /**
     * 检查算法是否收敛
     */
    private boolean hasConverged(List<ScheduleChromosome> population) {
        if (population == null || population.isEmpty()) {
            return false;
        }
        
        // 计算平均适应度
        double avgFitness = 0;
        for (ScheduleChromosome chromosome : population) {
            avgFitness += chromosome.getFitness();
        }
        avgFitness /= population.size();
        
        // 计算适应度标准差
        double variance = 0;
        for (ScheduleChromosome chromosome : population) {
            variance += Math.pow(chromosome.getFitness() - avgFitness, 2);
        }
        variance /= population.size();
        double stdDev = Math.sqrt(variance);
        
        // 如果标准差小于阈值，认为已收敛
        return stdDev < 1.0;
    }
    
    /**
     * 检查排课冲突
     * 
     * @param schedule 排课信息
     * @return 冲突信息列表
     */
    @Override
    public List<String> checkScheduleConflict(AcCourseSchedule schedule) {
        List<String> conflicts = new ArrayList<>();
        
        try {
            // 获取该学期的所有排课
            List<AcCourseSchedule> existingSchedules = courseScheduleMapper.selectAcCourseScheduleBySemesterId(schedule.getSemesterId());
            
            // 检查与现有排课的冲突
            for (AcCourseSchedule existing : existingSchedules) {
                // 检查时间冲突
                if (hasTimeConflict(schedule, existing)) {
                    // 检查教师冲突
                    if (schedule.getTeacherId().equals(existing.getTeacherId())) {
                        conflicts.add("教师时间冲突: 教师ID " + schedule.getTeacherId() + " 在 " + 
                                     schedule.getWeekDay() + " 第" + schedule.getStartWeek() + "-" + schedule.getEndWeek() + "周 已有课程安排");
                    }
                    
                    // 检查教室冲突
                    if (schedule.getClassroomId().equals(existing.getClassroomId())) {
                        conflicts.add("教室时间冲突: 教室ID " + schedule.getClassroomId() + " 在 " + 
                                     schedule.getWeekDay() + " 第" + schedule.getStartWeek() + "-" + schedule.getEndWeek() + "周 已有课程安排");
                    }
                    
                    // 检查班级冲突
                    if (schedule.getClassId().equals(existing.getClassId())) {
                        conflicts.add("班级时间冲突: 班级ID " + schedule.getClassId() + " 在 " + 
                                     schedule.getWeekDay() + " 第" + schedule.getStartWeek() + "-" + schedule.getEndWeek() + "周 已有课程安排");
                    }
                }
            }
            
            // 检查教室容量
            ScClassroom classroom = classroomService.selectScClassroomById(schedule.getClassroomId());
            ScClass classInfo = classService.selectScClassById(schedule.getClassId());
            
            if (classroom != null && classInfo != null && classroom.getCapacity() < classInfo.getStudentCount()) {
                conflicts.add("教室容量不足: 教室ID " + schedule.getClassroomId() + " 容量为 " + 
                             classroom.getCapacity() + "，班级ID " + schedule.getClassId() + " 学生数为 " + classInfo.getStudentCount());
            }
            
        } catch (Exception e) {
            logger.error("检查排课冲突失败: {}", e.getMessage(), e);
            conflicts.add("检查排课冲突时发生错误: " + e.getMessage());
        }
        
        return conflicts;
    }

    /**
     * 保存排课结果到数据库
     */
    private boolean saveScheduleToDatabase(List<AcCourseSchedule> schedules, String operateUser) {
        try {
            // 删除原有课表
            if (!schedules.isEmpty()) {
                Long semesterId = schedules.get(0).getSemesterId();
                AcCourseSchedule queryCondition = new AcCourseSchedule();
                queryCondition.setSemesterId(semesterId);
                courseScheduleMapper.deleteAcCourseScheduleBySemesterId(semesterId);
            }
            
            // 批量插入新课表
            for (AcCourseSchedule schedule : schedules) {
                schedule.setCreateBy(operateUser);
                schedule.setCreateTime(new Date());
                courseScheduleMapper.insertAcCourseSchedule(schedule);
            }
            
            logger.info("成功保存 {} 条课表记录", schedules.size());
            return true;
        } catch (Exception e) {
            logger.error("保存排课结果失败: {}", e.getMessage(), e);
            return false;
        }
    }
}